package com.lepu.app.fun.chat.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.os.Vibrator;
import android.text.TextUtils;
import android.util.Log;

import com.app.application.MyApplication;
import com.app.utils.LoginUtil;
import com.app.utils.ObserverConst;
import com.core.lib.utils.ObserverManager;
import com.core.lib.utils.main.AppManager;
import com.core.lib.utils.main.LogUtilBase;
import com.core.lib.utils.main.UtilityBase;
import com.lepu.app.fun.chat.activity.ChatMainActivity;
import com.lepu.app.fun.chat.bean.BeanChatTo;
import com.lepu.app.fun.chat.bean.BeanDoctorMy;
import com.lepu.app.fun.chat.bean.ChatError;
import com.lepu.app.fun.chat.bean.ChatMessage;
import com.lepu.app.fun.chat.bean.ChatRoomMessage;
import com.lepu.app.fun.chat.bean.ChatRoomSession;
import com.lepu.app.fun.chat.bean.ChatSession;
import com.lepu.app.fun.chat.bean.Media;
import com.lepu.app.fun.chat.business.DoctorManager;
import com.lepu.app.fun.chat.services.MediaService;
import com.lepu.app.fun.chat.util.AppCommonService;
import com.lepu.app.fun.chat.util.ChatConst;
import com.lepu.app.fun.chat.util.Constants;
import com.lepu.app.fun.chat.util.SingManager;
import com.lepu.app.fun.chat.util.TimeUtil;
import com.lepu.app.usercenter.bean.LoginInfo;

/**
 * Created by Chang on 12/29/2014. 聊天管理
 */
public class ChatManager implements IClientChat.XmppListener,
        MediaManager.MediaListener {
    private static Logger logger = LoggerFactory.getLogger(ChatManager.class);

    private String host;
    private int port;
    private long uid;
    private String pwd;
    private int loginState = Constants.Chat.CHAT_LOGIN_STATE_NEW;
    private Vibrator vibrate;

    private Map<String, ChatMessage> newMessages = new ConcurrentHashMap<String, ChatMessage>();
    private Map<String, ChatRoomMessage> newChatRoomMessages = new ConcurrentHashMap<String, ChatRoomMessage>();
    private List<ChatSession> chatSessions = new ArrayList<ChatSession>();
    private boolean isMonitorStopped = false;

    private IClientChat chatClient = null;

    static class ChatManagerHolder {
        static ChatManager manager = new ChatManager();
        // vibrator = (Vibrator)
        // getActivity().getSystemService(Context.VIBRATOR_SERVICE);

    }

    public static ChatManager getInstance() {
        return ChatManagerHolder.manager;
    }

    private ChatManager() {
        resetAllSentMessageSimple();
        resetAllSentMessageGroup();
        chatClient = ClientChatXmppImpl.getInstance();
        chatClient.setXmppListener(this);
    }

    // ********Public methods**************//

    public int getLoginState() {
        return loginState;
    }

    public void login(String host, int port, long userId, String pwd) {
        loginState = Constants.Chat.CHAT_LOGIN_STATE_STARTED;
        this.host = host;
        this.port = port;
        this.uid = userId;
        this.pwd = pwd;

        chatClient.login(host, port, userId, pwd);
    }

    public void logout() {
        Log.d("xmpp ", "退出成功");
        isMonitorStopped = true;
        chatClient.disconnect();
        loginState = Constants.Chat.CHAT_LOGIN_STATE_NEW;
    }

    public void sendMessage(ChatSession session, ChatMessage chatMessage) {
        try {
            // todo
            // if (!verifyOutGoingMessage(session, chatMessage)) {
            // logger.error("verifyOutGoingMessage failed");
            // return;
            // }
            // 1. add message to database
            ChatDAO.getInstance().replaceMessage(chatMessage);
            // 2.update session content and lastMsgTime to database
            session.setLastMsgContent(chatMessage.getContent());
            session.setLastMsgTime(chatMessage.getSendTime());

            ChatDAO.getInstance().updateChatSession(session);

            // 3. put message to Queue
            newMessages.put(chatMessage.getMessageId(), chatMessage);
            // 4. broadcast data change to UI
            notifyUIDataChange(session, chatMessage,
                    Constants.Chat.CHAT_MESSAGE_SENT);
            // 5. send out message, so receipt should arrive after steps 1 and 2
            chatClient.sendMessage(chatMessage);

        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    public void sendMessageNotice(ChatMessage chatMessage) {
        try {
            // todo
            // if (!verifyOutGoingMessage(session, chatMessage)) {
            // logger.error("verifyOutGoingMessage failed");
            // return;
            // }
            // 1. add message to database
            //ChatDAO.getInstance().replaceMessage(chatMessage);
            // 2.update session content and lastMsgTime to database
            //session.setLastMsgContent(chatMessage.getContent());
           //session.setLastMsgTime(chatMessage.getSendTime());

            //ChatDAO.getInstance().updateChatSession(session);

            // 3. put message to Queue
            //newMessages.put(chatMessage.getMessageId(), chatMessage);
            // 4. broadcast data change to UI
//            notifyUIDataChange(session, chatMessage,
//                    Constants.Chat.CHAT_MESSAGE_SENT);
            // 5. send out message, so receipt should arrive after steps 1 and 2
            chatClient.sendMessage(chatMessage);

        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    /**
     * 发送给在线咨询人员
     *
     * @param session
     * @param chatMessage
     */
    public void sendMessageToStaff(ChatSession session, ChatMessage chatMessage) {
        try {
            // if (!verifyOutGoingMessage(session, chatMessage)) {
            // logger.error("verifyOutGoingMessage failed");
            // return;
            // }
            // 1. add message to database
            chatMessage.setFromUserId(Constants.Staff); // 固定一个人
            chatMessage.setToUserId(session.getUserId());
            ChatDAO.getInstance().replaceMessage(chatMessage);

            // //2.update session content and lastMsgTime to database
//			session.setLastMsgContent(chatMessage.getContent());
//			session.setLastMsgTime(chatMessage.getSendTime());
//
//			ChatDAO.getInstance().updateChatSession(session);

            // 3. put message to Queue
            newMessages.put(chatMessage.getMessageId(), chatMessage);
            // 4. broadcast data change to UI
            notifyStaffOnlineChat(chatMessage, Constants.Chat.CHAT_MESSAGE_SENT);
            // notifyUIDataChange(session, chatMessage,
            // Constants.Chat.CHAT_MESSAGE_SENT);
            // 5. send out message, so receipt should arrive after steps 1 and 2
            chatClient.sendMessage(chatMessage);

        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }

    public void sendMessage(ChatSession session, ChatMessage chatMessage,
                            Boolean isMediaType) {
        try {

//            if (!verifyOutGoingMessage(session, chatMessage)) {
//                logger.error("verifyOutGoingMessage failed");
//                return;
//            }

            // 1. add message to database
            ChatDAO.getInstance().replaceMessage(chatMessage);

            // 2.update session content and lastMsgTime to database
            session.setLastMsgContent(chatMessage.getContent());
            session.setLastMsgTime(chatMessage.getSendTime());

            ChatDAO.getInstance().updateChatSession(session);

            // 3. put message to Queue
            newMessages.put(chatMessage.getMessageId(), chatMessage);

            // 4. broadcast data change to UI
            // notifyUIDataChange(session, chatMessage,
            // Constants.Chat.CHAT_MESSAGE_SENT);

            // 5. send out message, so receipt should arrive after steps 1 and 2
            chatClient.sendMessage(chatMessage);

        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
    }

    public void sendChatRoomMessage(ChatRoomSession session, ChatRoomMessage chatMessage) {
        try {
            //todo
//            if (!verifyOutGoingMessage(session, chatMessage)) {
//                logger.error("verifyOutGoingMessage failed");
//                return;
//            }
            //1. add message to database
            ChatDAO.getInstance().replaceChatRoomMessage(chatMessage);
            //2.update session content and lastMsgTime to database
//            session.setLastMsgContent(chatMessage.getContent());
//            session.setLastMsgTime(chatMessage.getSendTime());
            //// TODO: 2015/10/30
            //ChatDAO.getInstance().updateChatSession(session);

            //3. put message to Queue
            newChatRoomMessages.put(chatMessage.getMessageId(), chatMessage);
            //4. broadcast data change to UI

            Media media = chatMessage.getMedia();
            if(media == null)
            {
                notifyChatRoomUIDataChange(session, chatMessage, Constants.Chat.CHAT_MESSAGE_SENT);
            }else{
                //语音，图片，已经notify 了
            }

            //5. send out message, so receipt should arrive after steps 1 and 2
            chatClient.sendChatRoomMessage(chatMessage);

        } catch (Exception ex) {
            LogUtilBase.LogE(null, ex.toString());
        }
    }

    public void prepareSendMediaMessage(ChatSession session,
                                          ChatMessage chatMessage) {
        try {

            if (chatMessage.getMedia() == null) {
                logger.warn("no media to upload");
                return;
            }

            // 1. add message to database
            ChatDAO.getInstance().replaceMessage(chatMessage);

            // 2.update session lastMsgTime lastContent to database
            session.setLastMsgContent(chatMessage.getContent());
            session.setLastMsgTime(chatMessage.getSendTime());
            ChatDAO.getInstance().updateChatSession(session);

            // 3. broadcast data change to UI
            notifyUIDataChange(session, chatMessage,
                    Constants.Chat.CHAT_MESSAGE_SENT);

            // 4. send out async media message, so receipt should arrive after
            // steps 1 and 2
            startAsyncMediaOperation(MediaService.ACTION_UPLOAD_MEDIA,
                    chatMessage.getMedia());

        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
    }

    public void prepareSendMediaMessage(ChatRoomSession session,
                                        ChatRoomMessage chatMessage) {
        try {

            if (chatMessage.getMedia() == null) {
                logger.warn("no media to upload");
                return;
            }

            // 1. add message to database
            ChatDAO.getInstance().replaceChatRoomMessage(chatMessage);

            // 2.update session lastMsgTime lastContent to database
            //session.setLastMsgContent(chatMessage.getContent());
           // session.setLastMsgTime(chatMessage.getSendTime());
           // ChatDAO.getInstance().updateChatSession(session);

            // 3. broadcast data change to UI
            notifyChatRoomUIDataChange(session, chatMessage,
                    Constants.Chat.CHAT_MESSAGE_SENT);

            // 4. send out async media message, so receipt should arrive after
            // steps 1 and 2
            startAsyncMediaOperation(MediaService.ACTION_UPLOAD_MEDIA,
                    chatMessage.getMedia());

        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
    }

    public ChatSession getChatStaffSession(long sessionId) {
        try {
            return ChatDAO.getInstance().getChatSession(sessionId);
        } catch (Exception e) {
            logger.error(e.toString());
            return null;
        }
    }

    public List<ChatSession> getChatSessions() {
        try {
            return ChatDAO.getInstance().getChatSessions();
        } catch (Exception e) {
            logger.error(e.toString());
            return null;
        }
    }

    public List<ChatSession> getChatSessionsWithProductIcon() {
        List<ChatSession> sessionList = getChatSessions();
        // HashMap iconMap = AppContext.getAppContext().getCachePatientsMap();
        // Boolean isDoctorType = false;
        //
        // if (iconMap == null) {
        // if (isDoctorType) {
        // DoctorManager.getInstance().loadAndCachePatients();
        // } else {
        // PatientManager.getInstance().loadAndCacheDoctors();
        // }
        // iconMap = AppContext.getAppContext().getCachePatientsMap();
        // }
        //
        // if (iconMap != null) {
        // for (ChatSession item : sessionList) {
        // if (iconMap.get(item.getUserId()) != null) {
        // Doctor doctor = (Doctor) iconMap.get(item.getUserId());
        // item.productIconId = doctor.getProduct_icon_id();
        // item.product_leavel = doctor.getProduct_level();
        // }
        // }
        // }
        return sessionList;
    }

    public ChatSession getOrCreateChatSession(long hostId, BeanChatTo userInfo,
                                              String content, Date sendTime, int messageType) {
        try {
            long userID = UtilityBase.parseLong(userInfo.UserID);
            ChatSession session = ChatDAO.getInstance().getUserChatSession(
                    hostId, userID);
            if (null == session) {
                session = insertChatSession(hostId, userInfo, messageType,
                        content, sendTime);
                // String id = userInfo.productIconId == null ? "" :
                // userInfo.productIconId;
                session.productIconId = "";
            }

            if (null != session) {
                // 加上了头像 昵称 更新
                session.setUserProfilePictureId(userInfo.Avatar);// userInfo.getProfilePictureThumbnailId()
                session.setUserNickName(userInfo.NickName);
                session.productIconId = "";// userInfo.productIconId
                ChatDAO.getInstance().updateChatSession(session);
            }
            return session;
        } catch (Exception e) {
            logger.error(e.toString(), e);
            return null;
        }
    }

    /**
     * 在线咨询 staff
     */
    public ChatSession getOrCreateChatSessionStaff(long hostId, BeanChatTo userInfo, long sessionId) {
        try {
            return getOrCreateChatSessionStaff(hostId, userInfo, "", null,
                    Constants.Chat.CHAT_MESSAGE_SENT, sessionId);
        } catch (Exception e) {
            logger.error(e.toString(), e);
            return null;
        }
    }

    public ChatSession getOrCreateChatSessionStaff(long hostId, BeanChatTo userInfo,
                                                   String content, Date sendTime, int messageType, long sessionId) {
        try {
            long userID = UtilityBase.parseLong(userInfo.UserID);
            ChatSession session = ChatDAO.getInstance().getUserChatSession(
                    hostId, userID);
            if (null == session) {
                session = insertChatSession(hostId, userInfo, messageType,
                        content, sendTime);
                // String id = userInfo.productIconId == null ? "" :
                // userInfo.productIconId;
                session.productIconId = "";
            }

            if (null != session) {
                // 加上了头像 昵称 更新
                session.setUserProfilePictureId(userInfo.Avatar);// userInfo.getProfilePictureThumbnailId()
                session.setUserNickName(userInfo.NickName);
                session.productIconId = "";// userInfo.productIconId
                session.setSessionId(sessionId);
                ChatDAO.getInstance().updateChatSession(session);
            }
            return session;
        } catch (Exception e) {
            logger.error(e.toString(), e);
            return null;
        }
    }


    public List<ChatMessage> getChatMessages(long sessionId) {
        try {
            return ChatDAO.getInstance().getChatMessages(sessionId);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return null;
        }
    }

    public List<ChatMessage> getChatMessagesStaff(long sessionId,boolean isAll,int fromCount) {
        try {
            return ChatDAO.getInstance().getChatMessagesFromUserId(sessionId, isAll, fromCount);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return null;
        }
    }

    public List<ChatRoomMessage> getChatRoomMessages(String hostID, String chatRoomID) {
        try {
            return ChatDAO.getInstance().getChatRoomMessages(hostID, chatRoomID);
        } catch (Exception e) {
//            logger.error(e.getMessage());
            LogUtilBase.LogE(null, e.getMessage());
            return null;
        }
    }

    /**
     *
     * @param hostID
     * @param chatRoomID
     * @param isAll
     * @param fromCount
     * @return
     */
    public List<ChatRoomMessage> getChatRoomMessages(String hostID, String chatRoomID,boolean isAll,int fromCount,int pageSize) {
        try {
            return ChatDAO.getInstance().getChatRoomMessages(hostID, chatRoomID, isAll, fromCount,pageSize);
        } catch (Exception e) {
//            logger.error(e.getMessage());
            LogUtilBase.LogE(null, e.getMessage());
            return null;
        }
    }

    public List<ChatMessage> getChatMessages(String hostID, String sessionId,boolean isAll,int fromCount) {
        try {
            return ChatDAO.getInstance().getChatMessages(hostID, sessionId, isAll, fromCount);
        } catch (Exception e) {
//            logger.error(e.getMessage());
            LogUtilBase.LogE(null, e.getMessage());
            return null;
        }
    }

    public ChatSession getOrCreateChatSession(long hostId, BeanChatTo userInfo) {
        try {
            return getOrCreateChatSession(hostId, userInfo, "", null,
                    Constants.Chat.CHAT_MESSAGE_SENT);
        } catch (Exception e) {
            logger.error(e.toString(), e);
            return null;
        }
    }

    public void resetNewMsgCount(long sessionId) {
        try {
            ChatDAO.getInstance().reSetNewMsgCount(sessionId);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    public void resetChatMessages() {
        try {
            ChatDAO.getInstance().reSetChatMessages();
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    public void resetChatMessages(String DoctorID) {
        try {
            ChatDAO.getInstance().reSetChatMessages(DoctorID);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    public void resetChatSession(String DoctorID) {
        try {
            ChatDAO.getInstance().reSetChatSession(DoctorID);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    public void resetYuYinReadStateMessage(String msgID) {
        try {
            ChatDAO.getInstance().resetYuYinReadStateMessage(msgID);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    public void resetYuYinReadStateMessageRoom(String msgID) {
        try {
            ChatDAO.getInstance().resetYuYinReadStateMessageRoom(msgID);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    // ********Xmpp Listener callback methods**************//
    @Override
    public void onLogin() {
        loginState = Constants.Chat.CHAT_LOGIN_STATE_SUCCESS;
        logger.debug("chat login. logined=" + loginState);
        startListenIncomingMessages();
    }

    @SuppressLint("NewApi")
    @Override
    public void onServerTime(String tm) {
        logger.debug("onServerTime:" + tm);
        try {
            Date current = TimeUtil.toUTC(new Date());
            // format=2014-10-03T09:35:07Z
            String serverTime = tm.replace('T', ' ').replace('Z', ' ');
            if (!serverTime.isEmpty()) {
                Date serverUtcDate = TimeUtil.getUtcDateTime(serverTime);
                long localServerTimeDiff = current.getTime()
                        - serverUtcDate.getTime();
                TimeUtil.setLocalServerTimeDiff(localServerTimeDiff);
                logger.debug("chat Time in UTC:" + serverUtcDate
                        + ", local CurrentTime:" + current + ", TimeDiff:"
                        + localServerTimeDiff);
            } else {
                TimeUtil.setLocalServerTimeDiff(0);
                logger.warn("chat ServerTime is empty!");
            }

            startMonitorNewMessages();

        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    /**
     * 收到消息
     *
     * @param chatMessage
     */
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    @Override
    public void onReceiveMessage(ChatMessage chatMessage) {
        logger.debug("onReceiveMessage:" + chatMessage.getMessageId());

        // 1. get or create session for incoming message
        ChatSession chatSession = null;
        if (chatMessage.getSessionId() == 0) {
            chatSession = ChatDAO.getInstance().getChatSession(
                    chatMessage.getToUserId(), chatMessage.getFromUserId());
            if (null == chatSession) {
                // todo 数据库暂时没拿到
                BeanDoctorMy userInfo = getDoctor(chatMessage.getFromUserId());
                // UserInfo userInfo = new UserInfo();
                // userInfo.setUserId(10794);
                // userInfo.setNickName("pub");
                if (null != userInfo) {

                    BeanChatTo beanChatTo = new BeanChatTo();
                    beanChatTo.UserID = userInfo.DoctorID;
                    beanChatTo.Gender = userInfo.Gender;
                    beanChatTo.NickName = userInfo.DoctorName;
                    beanChatTo.Avatar = userInfo.UniqueID;

                    chatSession = getOrCreateChatSession(
                            chatMessage.getHostUserId(), beanChatTo,
                            chatMessage.getContent(),
                            chatMessage.getSendTime(),
                            Constants.Chat.CHAT_MESSAGE_RECEIVED);
                } else {
                    // TODO Chang need to handle this error?
                    logger.error("get UserInfo Error! Can't create ChatSession");
                    return;
                }
            }
        } else {
            chatSession = ChatDAO.getInstance().getChatSession(
                    chatMessage.getSessionId());
        }
        // chatSession = ChatDAO.getInstance().getChatSession(
        // chatMessage.getSessionId(),chatMessage.getFromUserId());

        // TODO what to do here?
        if (chatSession == null) {
            logger.error("ChatSession is null!");
            return;
        }

        int sendStatus = chatMessage.getSendStatus();
        ChatMainActivity chatMainActivity = (ChatMainActivity) AppManager.getAppManager().
                getActivity(ChatMainActivity.class);
        if(sendStatus != Constants.Chat.CHAT_SEND_STATUS_OFFLINE && chatMainActivity != null
                && chatMainActivity.mType == ChatConst.TYPE_ONLINE_CHAT_DOCTOR_MY)
        {
            //非离线消息，有声音
            SingManager.getInstance().setVoiceReminder();
        }

        // 2. insert new message
        chatMessage.setSessionId(chatSession.getSessionId());
        if (null == chatMessage.getGuestProfilePicId()
                || chatMessage.getGuestProfilePicId().isEmpty()) {
            chatMessage.setGuestProfilePicId(chatSession
                    .getUserProfilePictureId());
        }
        // ChatDAO.getInstance().updateMessage(chatMessage);
        ChatDAO.getInstance().insertMessage(chatMessage);

        //3. update session
        if(chatSession != null)
        {
            chatSession.setLastMsgTime(chatMessage.getSendTime());
            if(chatMessage.getMessageType() == Constants.Chat.CHAT_MESSAGE_TYPE_IMAGE)
            {
                chatSession.setLastMsgContent(Constants.Chat.CHAT_LAST_MSG_IMAGE_TEXT);
            }else if(chatMessage.getMessageType() == Constants.Chat.CHAT_MESSAGE_TYPE_AUDIO){
                chatSession.setLastMsgContent(Constants.Chat.CHAT_LAST_MSG_AUDIO_TEXT);
            }else if(chatMessage.getMessageType() == Constants.Chat.CHAT_MESSAGE_TYPE_VIDEO){
                chatSession.setLastMsgContent(Constants.Chat.CHAT_LAST_MSG_VIDEO_TEXT);
            }else{
                chatSession.setLastMsgContent(chatMessage.getContent());
            }

            chatSession.setNewMsgCount(chatSession.getNewMsgCount() + 1);
            ChatDAO.getInstance().updateChatSession(chatSession);

            if(chatSessions != null && chatSessions.size() > 0){
                for (int i = 0; i < chatSessions.size(); i++) {
                    if (chatSessions.get(i) != null && chatSessions.get(i).getSessionId() == chatSession.getSessionId()) {
                        chatSessions.set(i, chatSession);
                        break;
                    }
                }
            }else{
                chatSessions.add(chatSession);
            }
        }

        // 5. download media if it is a media message
        if (chatMessage.getMedia() != null) {
            // Download media async, for now, Image is download directly by
            // ImageLoader, so no actual download happen there
//            Media media = chatMessage.getMedia();
//            media.setSessionId(chatSession.getSessionId());
//            media.setMessageId(chatMessage.getMessageId());
//            startAsyncMediaOperation(MediaService.ACTION_DOWNLOAD_MEDIA, media);
            // MediaService -> MediaManager for actual file download and save to
            // local, then invoke onDownload callback to notify UI data ready

            notifyUIDataChange(chatSession, chatMessage,
                    Constants.Chat.CHAT_MESSAGE_RECEIVED);
        }else{
            // 4. update UI
            notifyUIDataChange(chatSession, chatMessage,
                    Constants.Chat.CHAT_MESSAGE_RECEIVED);
        }

        // 发消息红点展示
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_INDEX_CIRCLE, null, null);
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_INDEX_ZIXUN_DOCTOR_CHAT_CIRCLE, null,
                null);
    }

    /**
     * 扩展 增加来自客服的消息2015 8/18
     *
     * @param chatMessage
     */
    @Override
    public void onReceiveStaffMessage(ChatMessage chatMessage) {

        // todo 存储时用一个固定的值 默认-99
        chatMessage.setFromUserId(Constants.Staff);
        ChatDAO.getInstance().insertMessage(chatMessage);

        // 3. update session
//		ChatSession chatSession = ChatDAO.getInstance().getChatSession(
//				chatMessage.getSessionId());
//		if (chatSession != null) {
//			chatSession.setLastMsgTime(chatMessage.getSendTime());
//			chatSession.setLastMsgContent(chatMessage.getContent());
//			chatSession.setNewMsgCount(chatSession.getNewMsgCount() + 1);
//			ChatDAO.getInstance().updateChatSession(chatSession);
//		}
        LoginUtil.updateStaffMsgNewCount();

        int sendStatus = chatMessage.getSendStatus();
        ChatMainActivity chatMainActivity = (ChatMainActivity) AppManager.getAppManager().
                getActivity(ChatMainActivity.class);
        if(sendStatus != Constants.Chat.CHAT_SEND_STATUS_OFFLINE && chatMainActivity != null
                && chatMainActivity.mType == ChatConst.TYPE_ONLINE_CHAT_ONLINE)
        {
            //非离线消息，有声音
            SingManager.getInstance().setVoiceReminder();
        }

        // 4. update UI
        notifyStaffOnlineChat(chatMessage, Constants.Chat.CHAT_MESSAGE_RECEIVED);

        // 发消息红点展示
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_INDEX_CIRCLE, null, null);
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_INDEX_ZIXUN_ONLINE_CHAT_CIRCLE, null,
                null);
    }

    /**
     * 获得群组的消息
     *
     * @param chatMessage
     */
    @Override
    public void onReceiveGroupChatMessage(ChatRoomMessage chatMessage) {

        if (newChatRoomMessages.containsKey(chatMessage.getMessageId())) {
            //移除消息队列中未发送出去的消息
            newChatRoomMessages.remove(chatMessage.getMessageId());
        }
        //1.if myself message,to update ui right
        if (chatMessage.getFromUserId() == Long.valueOf(chatMessage.getToUserId())) {
            chatMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_RECEIVED);
            chatMessage.setDirection(Constants.Chat.CHAT_DIRECTION_SEND);
            //insert message to db
            ChatDAO.getInstance().replaceChatRoomMessage(chatMessage);
            notifyChatRoomUIDataChange(null, chatMessage, Constants.Chat.CHAT_MESSAGE_CHANGED);
            return;
        }
        //1.1 get 插头roomSession to update newCount
        //// TODO: 2015/11/22  modify reset msg count remove
        ChatRoomSession chatRoomSession = ChatDAO.getInstance().getChatRoomSession(LoginUtil.getUserId(), chatMessage.getChatRoomID());
        if (chatRoomSession == null) {
            chatRoomSession = ChatDAO.getInstance().getChatRoomSession(chatMessage.getChatRoomID());
        }
        if (chatRoomSession != null) {
            chatRoomSession.NewMessageCount = chatRoomSession.NewMessageCount + 1;
        }

        //2insert message to db
        ChatDAO.getInstance().replaceChatRoomMessage(chatMessage);
        //2.1 update chatroom_session
        ChatDAO.getInstance().updateChatRoomSession(chatRoomSession);
        //3.if others message,to update ui left
        //首页新消息红点
//		if (MyApplication.getInstance().getCounTitleHandler() != null)
//			MyApplication.getInstance().getCounTitleHandler().sendEmptyMessage(2);

        int sendStatus = chatMessage.getSendStatus();
        ChatMainActivity chatMainActivity = (ChatMainActivity) AppManager.getAppManager().
                getActivity(ChatMainActivity.class);
        if(sendStatus != Constants.Chat.CHAT_SEND_STATUS_OFFLINE && chatMainActivity != null
                && chatMainActivity.mType == ChatConst.TYPE_ONLINE_CHAT_LECTURE)
        {
            //非离线消息，有声音
            SingManager.getInstance().setVoiceReminder();
        }

        // 5. download media if it is a media message
        if (chatMessage.getMedia() != null) {

            //4. update UI
            //原来是直接添加到UI，下载成功或失败后更新UI.
            notifyChatRoomUIDataChange(chatRoomSession, chatMessage, Constants.Chat.CHAT_MESSAGE_RECEIVED);

            // Download media async, for now, Image is download directly by
            // ImageLoader, so no actual download happen there

            //下载成功后添加到ui
//            Media media = chatMessage.getMedia();
//            media.setSessionId(0);
//            media.setMessageId(chatMessage.getMessageId());
//            startAsyncMediaOperation(MediaService.ACTION_DOWNLOAD_MEDIA, media);

            // MediaService -> MediaManager for actual file download and save to
            // local, then invoke onDownload callback to notify UI data ready
        }else{
            //4. update UI
            notifyChatRoomUIDataChange(chatRoomSession, chatMessage, Constants.Chat.CHAT_MESSAGE_RECEIVED);
        }

        // 发消息红点展示
//        ObserverManager.getInstance().notifyAsync(
//                ObserverConst.NOTIFY_CHAT_INDEX_CIRCLE, null, null);
//        ObserverManager.getInstance().notifyAsync(
//                ObserverConst.NOTIFY_CHAT_INDEX_ZIXUN_DOCTOR_CHAT_CIRCLE, null,
//                null);
    }

    @Override
    public void onReceiveReceipt(ChatMessage receivedMessage) {
        logger.debug("onReceiveReceipt:" + receivedMessage.getMessageId());

        // 1. if message id in newMessage Queue, so remove it to prevent Offline
        // Query
        ChatMessage localMessage = null;
        if (newMessages.containsKey(receivedMessage.getMessageId())) {
            localMessage = newMessages.get(receivedMessage.getMessageId());
            newMessages.remove(receivedMessage.getMessageId());
        }
        ChatMessage.MessageReceipt receipt = receivedMessage.getReceipt();

        // 2. update message in database
        if (localMessage == null)
            localMessage = ChatDAO.getInstance().getChatMessage(
                    receivedMessage.getMessageId());

        if (localMessage == null) {
            logger.error("ChatMessage " + receivedMessage.getMessageId()
                    + " not found");
            return;
        }
        // for remote receipt
        if (receivedMessage.getFromUserId() != Constants.Chat.CHAT_FROM_SERVER_ID) {
            localMessage
                    .setSendStatus(Constants.Chat.CHAT_SEND_STATUS_RECEIVED);// 接收
            localMessage.setReceiveTime(TimeUtil.getAdjustDateTime(TimeUtil
                    .getCurrentTimeInUTC()));
        }
        // for server returned offline,don't update receive time until we get
        // real receipt from remote
        else if (receipt.getReason().equals("offline")) {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_OFFLINE); // 离线
        } else if (receipt.getReason().equals("normal")) {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_RECEIVED); // 发送成功
        }else if (receipt.getReason().equals("stranger")) {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_USER_FORBIDEN); // 禁言 不是医患关系
        }  else {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_BLOCKED); // 阻塞等待状态
        }

        ChatDAO.getInstance().updateMessage(localMessage);
        // todo 8/19 进行更新....UI 发送的状态
        if (localMessage.getFromUserId() == Constants.Staff) {
            notifyStaffOnlineChat(localMessage,
                    Constants.Chat.CHAT_MESSAGE_CHANGED);
        }

        ChatSession chatSession = ChatDAO.getInstance().getChatSession(
                localMessage.getSessionId());

        // 3. broadcast data chnage to UI
        if (null != chatSession) {
            notifyUIDataChange(chatSession, localMessage,
                    Constants.Chat.CHAT_MESSAGE_CHANGED);
        }
    }

    @Override
    public void onReceiveReceiptRoom(ChatRoomMessage receivedMessage) {
        logger.debug("onReceiveReceiptRoom:" + receivedMessage.getMessageId());

        // 1. if message id in newMessage Queue, so remove it to prevent Offline
        // Query
        ChatRoomMessage localMessage = null;
        if (newChatRoomMessages.containsKey(receivedMessage.getMessageId())) {
            localMessage = newChatRoomMessages.get(receivedMessage.getMessageId());
            newChatRoomMessages.remove(receivedMessage.getMessageId());
        }
        ChatRoomMessage.MessageReceipt receipt = receivedMessage.getReceipt();

        // 2. update message in database
        if (localMessage == null)
            localMessage = ChatDAO.getInstance().getChatRoomMessage(
                    receivedMessage.getMessageId());

        if (localMessage == null) {
            logger.error("ChatMessage " + receivedMessage.getMessageId()
                    + " not found");
            return;
        }
        // for remote receipt
        if (receivedMessage.getFromUserId() != Constants.Chat.CHAT_FROM_SERVER_ID) {
            localMessage
                    .setSendStatus(Constants.Chat.CHAT_SEND_STATUS_RECEIVED);// 接收
            localMessage.setReceiveTime(TimeUtil.getAdjustDateTime(TimeUtil
                    .getCurrentTimeInUTC()));
        }
        // for server returned offline,don't update receive time until we get
        // real receipt from remote
        else if (receipt.getReason().equals("offline")) {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_OFFLINE); // 离线
        } else if (receipt.getReason().equals("blocked")) {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_USER_FORBIDEN); // 禁言
        }else if (receipt.getReason().equals("normal")) {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_RECEIVED); // 发送成功
        }  else {
            localMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_BLOCKED); // 阻塞等待状态
        }

        ChatDAO.getInstance().updateMessage(localMessage);

        notifyChatRoomUIDataChange(null, localMessage, Constants.Chat.CHAT_MESSAGE_CHANGED);
        // todo 8/19 进行更新....UI 发送的状态
//		if (localMessage.getFromUserId() == Constants.Staff) {
//			notifyStaffOnlineChat(localMessage,
//					Constants.Chat.CHAT_MESSAGE_CHANGED);
//		}

//		ChatSession chatSession = ChatDAO.getInstance().getChatSession(
//				localMessage.getSessionId());
//
//		// 3. broadcast data chnage to UI
//		if (null != chatSession) {
//			notifyUIDataChange(chatSession, localMessage,
//					Constants.Chat.CHAT_MESSAGE_CHANGED);
//		}
    }

    /**
     * 语音消息
     *
     * @param iq
     */
    @Override
    public void onIQMessage(MessageStateIQ iq) {
        logger.debug("onIQMessage:" + iq);
        String messageId = iq.getPacketId();

        if (newMessages.containsKey(messageId)) {
            int code = iq.getCode();

            logger.debug("Find Message in newMessages Queue:" + messageId);
            ChatMessage chatMessage = newMessages.get(messageId);
            if (chatMessage != null)
                newMessages.remove(messageId);
            else {
                chatMessage = ChatDAO.getInstance().getChatMessage(messageId);
            }

            if (code == Constants.Chat.CHAT_MESSAGE_CODE_OFFLINE) {
                chatMessage
                        .setSendStatus(Constants.Chat.CHAT_SEND_STATUS_OFFLINE);
            } else if (code == Constants.Chat.CHAT_MESSAGE_CODE_NOFOUND) {
                chatMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_LOST);
            } else if (code == Constants.Chat.CHAT_MESSAGE_CODE_BLOCKED) {
                chatMessage
                        .setSendStatus(Constants.Chat.CHAT_SEND_STATUS_BLOCKED);
            } else {
                logger.debug("Result OfflineMessageIQ message:" + messageId
                        + " has INVALID Code:" + code);
                return;
            }

            ChatDAO.getInstance().updateMessage(chatMessage);
            ChatSession chatSession = ChatDAO.getInstance().getChatSession(
                    chatMessage.getSessionId());
            if (null == chatSession) {
                logger.error("Strange Error: session is not exist");
                return;
            }

            notifyUIDataChange(chatSession, chatMessage,
                    Constants.Chat.CHAT_MESSAGE_CHANGED);

        } else {
            logger.warn("IQMessage - Message was not found: " + messageId);
        }
    }

    @Override
    public void onXmppError(long sessionId, String messageId,
                            ChatError chatError) {
        logger.debug("onXmppError sessionId:" + sessionId + " messageId:"
                + messageId + " error:" + chatError);
        // TODO Chang need to update message status

        if (chatError.getErrorType() == Constants.Error.XMPP_CONNECTION_ERROR) {
            // logout();
            // login(this.host, this.port, this.uid, this.pwd);
        } else if (chatError.getErrorType() == Constants.Error.XMPP_LOGIN_ERROR) {
            loginState = Constants.Chat.CHAT_LOGIN_STATE_ERROR;
        }

        // 暂时先不处理
    }

    // ********MediaListener callback methods**************//
    @Override
    public void onUpload(Media media) {
        logger.debug("onUpload media " + media.getFullName()
                + " for sessionId:" + media.getSessionId() + ", messageId:"
                + media.getMessageId());

        if (null != media) {

            String groupchat = media.getChatType();
            if(!TextUtils.isEmpty(groupchat) && groupchat.equals(Constants.Chat.GROUPCHAT))
            {
                ChatRoomMessage chatMessage = ChatDAO.getInstance().getChatRoomMessage(
                        media.getMessageId());
                chatMessage.setMedia(media);

                chatMessage.setMessageType(media.getMessageType());

                sendChatRoomMessage(new ChatRoomSession(), chatMessage);
            }else{
                ChatSession chatSession = null;
                for (ChatSession session : chatSessions) {
                    if (session.getSessionId() == media.getSessionId()) {
                        chatSession = session;
                        break;
                    }
                }

                ChatMessage chatMessage = ChatDAO.getInstance().getChatMessage(
                        media.getMessageId());
                chatMessage.setMedia(media);

                chatMessage.setMessageType(media.getMessageType());

                sendMessage(chatSession, chatMessage, true);
            }
        }
    }

    @Override
    public void onDownload(Media media) {
        logger.debug("onDownload media " + media.getObjectId()
                + " for sessionId:" + media.getSessionId() + ", messageId:"
                + media.getMessageId());

        if (null != media) {

            String groupchat = media.getChatType();
            if(!TextUtils.isEmpty(groupchat) && groupchat.equals(Constants.Chat.GROUPCHAT))
            {
                ChatRoomMessage chatMessage = ChatDAO.getInstance().getChatRoomMessage(
                        media.getMessageId());
                chatMessage.setMedia(media);

                chatMessage.setMessageType(media.getMessageType());

                ChatDAO.getInstance().replaceChatRoomMessage(chatMessage);
                //原来是收到图片，语音消息，先添加到UI。下载成功或失败后，再更新UI。
//                notifyChatRoomUIDataChange(new ChatRoomSession(), chatMessage,
//                        Constants.Chat.CHAT_MESSAGE_CHANGED);

                //现在是收到图片，语音消息。下载成功或失败后，添加到UI。
                notifyChatRoomUIDataChange(new ChatRoomSession(), chatMessage,
                        Constants.Chat.CHAT_MESSAGE_RECEIVED);
            }else{
                ChatSession chatSession = null;
                for (ChatSession session : chatSessions) {
                    if (session.getSessionId() == media.getSessionId()) {
                        chatSession = session;
                        break;
                    }
                }

                ChatMessage chatMessage = ChatDAO.getInstance().getChatMessage(
                        media.getMessageId());
                chatMessage.setMedia(media);
                chatMessage.setMessageType(media.getMessageType());
                // todo by chengl
                ChatDAO.getInstance().replaceMessage(chatMessage);
                notifyUIDataChange(chatSession, chatMessage,
                        Constants.Chat.CHAT_MESSAGE_CHANGED);
            }
        }
    }

    @Override
    public void onMediaError(long sessionId, String messageId, Media media,
                             ChatError chatError) {
        logger.debug("onXmppError sessionId:" + sessionId + " messageId:"
                + messageId + " error:" + chatError);
        // TODO Chang need to update message status

        if(media != null)
        {
            String groupchat = media.getChatType();
            if(!TextUtils.isEmpty(groupchat) && groupchat.equals(Constants.Chat.GROUPCHAT))
            {
                ChatRoomMessage chatRoomMessage = ChatDAO.getInstance().getChatRoomMessage(
                        media.getMessageId());
                chatRoomMessage.setMedia(media);

                chatRoomMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_UPLOAD_FAILED);
                ChatDAO.getInstance().updateMessagesStatusRoom(chatRoomMessage.getMessageId(),
                        Constants.Chat.CHAT_SEND_STATUS_UPLOAD_FAILED);

                notifyChatRoomUIDataChange(new ChatRoomSession(),
                        chatRoomMessage, Constants.Chat.CHAT_MESSAGE_CHANGED);
            }else{
                ChatSession chatSession = null;
                for (ChatSession session : chatSessions) {
                    if (session.getSessionId() == sessionId) {
                        chatSession = session;
                        break;
                    }
                }
                ChatMessage chatMessage = ChatDAO.getInstance().getChatMessage(
                        messageId);
                chatMessage
                        .setSendStatus(Constants.Chat.CHAT_SEND_STATUS_UPLOAD_FAILED);
                chatMessage.setMedia(media);
                ChatDAO.getInstance().updateMessagesStatus(chatMessage.getMessageId(),
                        Constants.Chat.CHAT_SEND_STATUS_UPLOAD_FAILED);
                notifyUIDataChange(chatSession, chatMessage,
                        Constants.Chat.CHAT_MESSAGE_CHANGED);
            }
        }
    }

    // ********Private methods**************//
    void startListenIncomingMessages() {
        chatClient.listenIncomingMessages();
    }

    private void startMonitorNewMessages() {
        Thread monitor = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        if (isMonitorStopped) {
                            logger.debug("Quit from MonitorNewMessages thread!");
                            return;
                        }
                        queryIQProc();
                        Thread.sleep(AppCommonService.getInstance()
                                .getOfflineMsgIQQueryTime());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });

        monitor.setPriority(Thread.MIN_PRIORITY);
        monitor.start();
    }

    /**
     * 消息重发机制 5s 重发机制
     */
    private void queryIQProc() {
        for (String key : newMessages.keySet()) {
            ChatMessage chatMessage = newMessages.get(key);
            if (chatMessage.getQueryTryCount() == 0) {
                // First time query need to wait at least 5s
                if (chatMessage.getElapsed() > AppCommonService.getInstance()
                        .getOfflineMsgIQQueryTime()) {
                    chatMessage.setQueryTryCount(1);
                    chatClient.sendMessageIQ(chatMessage.getFromUserId(),
                            chatMessage.getToUserId(),
                            chatMessage.getMessageId());
                    logger.debug("queryIQProc #1 try for:"
                            + chatMessage.getMessageId());
                }
            } else if (chatMessage.getQueryTryCount() == 1) {
                chatMessage.setQueryTryCount(2);
                chatClient.sendMessageIQ(chatMessage.getFromUserId(),
                        chatMessage.getToUserId(), chatMessage.getMessageId());
                logger.debug("queryIQProc #2 try for:"
                        + chatMessage.getMessageId());
            } else {
                chatMessage.setSendStatus(Constants.Chat.CHAT_SEND_STATUS_LOST);
                ChatDAO.getInstance().updateMessage(chatMessage);
                newMessages.remove(key);
                logger.debug("queryIQProc After #2 try for:"
                        + chatMessage.getMessageId());
                ChatSession chatSession = ChatDAO.getInstance().getChatSession(
                        chatMessage.getSessionId());
                if (null != chatSession) {
                    notifyUIDataChange(chatSession, chatMessage,
                            Constants.Chat.CHAT_MESSAGE_CHANGED);
                } else {
                    notifyStaffOnlineChat(chatMessage,
                            Constants.Chat.CHAT_MESSAGE_CHANGED);
                }
            }
        }
    }

    private ChatSession insertChatSession(long hostUserId, BeanChatTo userInfo,
                                          int messageType, String content, Date lastMsgDateTime) {
        try {
            return ChatDAO.getInstance().insertChatSession(hostUserId,
                    userInfo, messageType, content, lastMsgDateTime);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return null;
        }
    }

    private BeanDoctorMy getDoctor(long DoctorId) {
        BeanDoctorMy doctor = DoctorManager.getInstance().getDoctorfromDB(
                DoctorId);

        return doctor;
    }

    private void startAsyncMediaOperation(String action, Media media) {
        Intent intent = new Intent(MyApplication.getInstance(),
                MediaService.class);
        intent.setAction(action);
        Bundle data = new Bundle();
        data.putSerializable(Constants.Chat.CHAT_MEDIA, media);

        intent.putExtras(data);
        MyApplication.getInstance().startService(intent);
    }

    public void notifyUIDataChange(ChatSession session, ChatMessage message,
                                    int what) {
        // todo 老chatseesion 是否为null chatsession list 会中间空位置 2 新消息和就消息
        if (chatSessions == null) {
            chatSessions = new ArrayList<ChatSession>();
        }

        boolean isNew = true;

        for (int i = 0; i < chatSessions.size(); i++) {
            if (chatSessions.get(i).getSessionId() == session.getSessionId()) {
                chatSessions.set(i, session);
                isNew = false;
                break;
            }
        }

        if (isNew)
            chatSessions.add(session);

        notifyAppContext(what, session, message);
    }

    private void notifyAppContext(int what, ChatSession session,
                                  ChatMessage message) {

        // 医生聊天列表
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_MESSAGE_DOCTOR, what, message);

        // 医生聊天记录 session列表
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_DOCTOR_SESSION, what, session);

    }

    private void resetAllSentMessageSimple() {
        try {
            ChatDAO.getInstance().updateAllSentMessageSimple();
        } catch (Exception ex) {
            logger.error(ex.toString(), ex);
        }
    }

    private void resetAllSentMessageGroup() {
        try {
            ChatDAO.getInstance().updateAllSentMessageGroup();
        } catch (Exception ex) {
            logger.error(ex.toString(), ex);
        }
    }

    @SuppressLint("NewApi")
    private boolean verifyOutGoingMessage(ChatSession session,
                                          ChatMessage chatMessage) {
        boolean isValid = false;

        if (session == null) {
            logger.error("Invalid Outgoing Message: Session is null");
            return isValid;
        }

        if (session.getSessionId() == 0) {
            logger.error("Invalid Outgoing Message: SessionId is zero");
            return isValid;
        }

        if (session.getHostUserId() == session.getUserId()) {
            logger.error("Invalid Outgoing Message: Session HostUserId is same as (to)UserId");
            return isValid;
        }

        String patientId = LoginUtil.getUserId();
        if (session.getHostUserId() != Long.valueOf(patientId)) {
            logger.error("Invalid Outgoing Message: Session HostUserId is not same as CurrentUser Id");
            return isValid;
        }

        if (chatMessage == null) {
            logger.error("Invalid Outgoing Message: chatMessage is null");
            return isValid;
        }
        if (chatMessage.getSessionId() == 0) {
            logger.error("Invalid Outgoing Message: chatMessage sessionId is zero");
            return isValid;
        }

        if (chatMessage.getMessageId() == null
                || chatMessage.getMessageId().isEmpty()) {
            logger.error("Invalid Outgoing Message: chatMessage messageId is null or empty");
            return isValid;
        }

        if (chatMessage.getSendStatus() != Constants.Chat.CHAT_SEND_STATUS_SENT) {
            logger.error("Invalid Outgoing Message: chatMessage status has an invalid value - "
                    + chatMessage.getSendStatus());
            return isValid;
        }
        return true;
    }

    public void notifyStaffOnlineChat(ChatMessage message, int what) {

        // 在线咨询聊天列表
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_MESSAGE_ONLINE, what, message);
    }

    /**
     * 通知聊天ui进行更新
     *
     * @param session
     * @param message
     * @param what
     */
    public void notifyChatRoomUIDataChange(ChatRoomSession session, ChatRoomMessage message, int what) {

        // 讲座聊天列表
        ObserverManager.getInstance().notifyAsync(
                ObserverConst.NOTIFY_CHAT_MESSAGE_LECTURE, what, message);

        // 讲座 session列表
//		ObserverManager.getInstance().notifyAsync(
//				ObserverConst.NOTIFY_CHAT_ROOM_LECTURE_SESSION, what, session);

    }

}
